package com.quectel.mobile.interceptor;

import com.quectel.constant.global.SystemConstants;
import com.quectel.mobile.constants.MobileSystemConstants;
import com.quectel.util.common.JacksonUtils;
import com.quectel.util.common.Response;
import com.quectel.util.redis.RedisUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.AsyncHandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @author: rananxin
 * @email: ryan.ran@quectel.com
 * @date: 2019-02-28 17:37:00
 */
@Component
public class LoginInterceptor implements AsyncHandlerInterceptor, WebMvcConfigurer {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            //请求的不是方法
            return true;
        }
        //h5相关接口拦截器
        String token = request.getHeader("token");
        if (StringUtils.isBlank(token)) {
            token = request.getParameter("token");
        }
        if (StringUtils.isBlank(token)) {
            writeError(response, Response.customize(MobileSystemConstants.TOKEN_IS_NULL_CODE, MobileSystemConstants.TOKEN_IS_NULL_MSG));
            return false;
        }
        String sessionStr = RedisUtils.get(MobileSystemConstants.TOKEN_USER_SESSION + token);
        if (StringUtils.isBlank(sessionStr)) {
            writeError(response, Response.customize(MobileSystemConstants.TOKEN_EXPIRED_CODE, MobileSystemConstants.TOKEN_EXPIRED_MSG));
            return false;
        }

        LoginMobileUserSession loginUserInfo = JacksonUtils.parse(sessionStr, LoginMobileUserSession.class);
        //重新设置时间
        RedisUtils.expire(MobileSystemConstants.TOKEN_USER_SESSION + token,
                SystemConstants.LoginType.JS_API.getType().equals(loginUserInfo.getLoginType())
                        ? MobileSystemConstants.JSAPI_EXPIRE_TIME : MobileSystemConstants.APP_EXPIRE_TIME
                , TimeUnit.SECONDS);

        if (loginUserInfo.getMobileUser() != null) {
            RedisUtils.expire(MobileSystemConstants.USER_TOKEN_SESSION + loginUserInfo.getMobileUser().getId(),
                    SystemConstants.LoginType.JS_API.getType().equals(loginUserInfo.getLoginType())
                            ? MobileSystemConstants.JSAPI_EXPIRE_TIME : MobileSystemConstants.APP_EXPIRE_TIME
                    , TimeUnit.SECONDS);
        }

        //方便controller获取
        request.setAttribute(MobileSystemConstants.TOKEN_USER_SESSION, JacksonUtils.parse(sessionStr, LoginMobileUserSession.class));
        return true;
    }

    private void writeError(HttpServletResponse response, Response result) {
        try {
            ServletOutputStream out = response.getOutputStream();
            out.write(JacksonUtils.toJsonString(result).getBytes("utf-8"));
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(this)
                .addPathPatterns("/**")
                .excludePathPatterns("/*.html")
                .excludePathPatterns("/*.js")
                .excludePathPatterns("/payNotify/**")
                .excludePathPatterns("/welcome")
                .excludePathPatterns("/banner/*")
                .excludePathPatterns("/notice/*")
                .excludePathPatterns("/helpCenter/*")
                .excludePathPatterns("/mobileUser/JSAPI/login")
                .excludePathPatterns("/mobileUser/sendBindingMsgCode")
                .excludePathPatterns("/entranceGuardVisitorApplyRecord/info/*")
                .excludePathPatterns("/forumPost/list/**")
                .excludePathPatterns("/forumPost/info/**")
                .excludePathPatterns("/forumComment/list/**")
                .excludePathPatterns("/forumComment/commentList/**")
                .excludePathPatterns("/forumComment/info/**")
                .excludePathPatterns("/forumTopic/info/**")
                .excludePathPatterns("/forumTopic/queryList/**")
                //openapi
                .excludePathPatterns("/v3/api-docs/**", "/swagger-ui.html");
    }

}
